/**
 * Block方块类
 * 	这是一个4*4的方块
 * 	包含属性：data --方块的数据
 * 			 origin --方块的起始点
 */
class Block{
	constructor(){
		if(new.target === Block){
			throw new Error('不能直接实例化')
		}
		this.data = [
			[0,2,0,0],
			[0,2,0,0],
			[0,2,0,0],
			[0,2,0,0]
		];
		this.origin = {
			x: 0,
			y: 0
		};
		//旋转数组
		this.rotates = [
			[
				[0,2,0,0],
				[0,2,0,0],
				[0,2,0,0],
				[0,2,0,0]
			],
			[
				[0,0,0,0],
				[2,2,2,2],
				[0,0,0,0],
				[0,0,0,0]
			],
			[
				[0,0,2,0],
				[0,0,2,0],
				[0,0,2,0],
				[0,0,2,0]
			],
			[
				[0,0,0,0],
				[0,0,0,0],
				[2,2,2,2],
				[0,0,0,0]
			]
		];
		//旋转索引
		this.dir = 0;
	}

	/**
	 * 是否可以下降
	 * @param  {function} isValid 检测数据是否合理
	 * @return {Boolean}          true 合理: false 不合理
	 */
	canRotate(isValid, that){
		let d = (this.dir + 1) % 4;
		let test = [
			[0,0,0,0],
			[2,2,2,2],
			[0,0,0,0],
			[0,0,0,0]
		];
		for(let i=0; i<this.data.length; i++){
			for(let j=0; j<this.data[0].length; j++){
				test[i][j] = this.rotates[d][i][j];
			}
		}
		return that.isValid(this.origin, test);
	}
	/**
	 * 方块旋转
	 * @return {[type]} [description]
	 */
	rotate(num){
		if(!num){
			num = 1;
		}
		this.dir = (this.dir + num) % 4;
		for(let i=0; i<this.data.length; i++){
			for(let j=0; j<this.data[0].length; j++){
				this.data[i][j] = this.rotates[this.dir][i][j];
			}
		}
	}

	/**
	 * 是否可以下降
	 * @param  {function} isValid 检测数据是否合理
	 * @return {Boolean}          true 合理: false 不合理
	 */
	canDown(isValid, that){
		let testOrigin = {};
		testOrigin.x = this.origin.x + 1;
		testOrigin.y = this.origin.y;
		return that.isValid(testOrigin, this.data);
	}
	/**
	 * 方块下落一格
	 * @return {[type]} [description]
	 */
	down(){
		this.origin.x ++;
	}

	/**
	 * 是否可以左移
	 * @param  {function} isValid 检测数据是否合理
	 * @param  {Object} that 指向调用isValid对象
	 * @return {Boolean}          true 合理: false 不合理
	 */
	canLeft(isValid, that){
		let testOrigin = {};
		testOrigin.x = this.origin.x;
		testOrigin.y = this.origin.y - 1;
		return that.isValid(testOrigin, this.data);
	}
	/**
	 * 方块左移一格
	 * @return {[type]} [description]
	 */
	left(){
		this.origin.y --;
	}

	/**
	 * 是否可以右移
	 * @param  {function} isValid 检测数据是否合理
	 * @return {Boolean}          true 合理: false 不合理
	 */
	canRight(isValid, that){
		let testOrigin = {};
		testOrigin.x = this.origin.x;
		testOrigin.y = this.origin.y + 1;
		return that.isValid(testOrigin, this.data);
	}
	/**
	 * 方块右移一格
	 * @return {[type]} [description]
	 */
	right(){
		this.origin.y ++;
	}
}


/**
 * 对Block的继承
 */
class Block1 extends Block{
	constructor(){
		if(new.target === Block1){
			super();
			this.data = [
				[0,0,0,0],
				[0,2,2,0],
				[0,2,2,0],
				[0,0,0,0]
			];
			this.rotates = [
				[
					[0,0,0,0],
					[0,2,2,0],
					[0,2,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,0],
					[0,2,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,0],
					[0,2,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,0],
					[0,2,2,0],
					[0,0,0,0]
				]
			];
		}
	}
}

class Block2 extends Block{
	constructor(){
		super();
		if(new.target === Block2){
			this.data = [
				[0,0,0,0],
				[0,0,2,0],
				[2,2,2,0],
				[0,0,0,0]
			];
			this.rotates = [
				[
					[0,2,0,0],
					[0,2,0,0],
					[0,2,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,2],
					[0,2,0,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,0],
					[0,0,2,0],
					[0,0,2,0]
				],
				[
					[0,0,0,0],
					[0,0,2,0],
					[2,2,2,0],
					[0,0,0,0]
				]
			];
		}
	}
}

class Block3 extends Block{
	constructor(){
		super();
		if(new.target === Block3){
			this.data = [
				[0,0,0,0],
				[0,2,0,0],
				[2,2,2,0],
				[0,0,0,0]
			];
			this.rotates = [
				[
					[0,0,0,0],
					[0,2,0,0],
					[2,2,2,0],
					[0,0,0,0]
				],
				[
					[0,2,0,0],
					[0,2,2,0],
					[0,2,0,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,2],
					[0,0,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,0,2,0],
					[0,2,2,0],
					[0,0,2,0]
				]
			];
		}
	}
}

class Block4 extends Block{
	constructor(){
		super();
		if(new.target === Block4){
			this.data = [
				[0,0,0,0],
				[0,0,0,0],
				[2,2,2,2],
				[0,0,0,0]
			];
			this.rotates = [
				[
					[0,2,0,0],
					[0,2,0,0],
					[0,2,0,0],
					[0,2,0,0]
				],
				[
					[0,0,0,0],
					[2,2,2,2],
					[0,0,0,0],
					[0,0,0,0]
				],
				[
					[0,0,2,0],
					[0,0,2,0],
					[0,0,2,0],
					[0,0,2,0]
				],
				[
					[0,0,0,0],
					[0,0,0,0],
					[2,2,2,2],
					[0,0,0,0]
				]
			];
		}
	}
}

class Block5 extends Block{
	constructor(){
		super();
		if(new.target === Block5){
			this.data = [
				[0,0,0,0],
				[0,0,2,0],
				[0,2,2,0],
				[0,0,0,0]
			];
			this.rotates = [
				[
					[0,0,0,0],
					[0,0,2,0],
					[0,2,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,0,0],
					[0,2,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,0],
					[0,2,0,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,0],
					[0,0,2,0],
					[0,0,0,0]
				]
			];
		}
	}
}

class Block6 extends Block{
	constructor(){
		super();
		if(new.target === Block6){
			this.data = [
				[0,0,0,0],
				[2,2,2,0],
				[2,0,0,0],
				[0,0,0,0]
			];
			this.rotates = [
				[
					[0,0,0,0],
					[2,2,2,0],
					[2,0,0,0],
					[0,0,0,0]
				],
				[
					[0,2,2,0],
					[0,0,2,0],
					[0,0,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,0,0,2],
					[0,2,2,2],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,0,0],
					[0,2,0,0],
					[0,2,2,0]
				]
			]
		}
	}
}

class Block7 extends Block{
	constructor(){
		super();
		if(new.target === Block7){
			this.data = [
				[0,0,0,0],
				[2,2,2,0],
				[2,0,2,0],
				[0,0,0,0]
			];
			this.rotates = [
				[
					[0,0,0,0],
					[2,2,2,0],
					[2,0,2,0],
					[0,0,0,0]
				],
				[
					[0,2,2,0],
					[0,0,2,0],
					[0,2,2,0],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,0,2],
					[0,2,2,2],
					[0,0,0,0]
				],
				[
					[0,0,0,0],
					[0,2,2,0],
					[0,2,0,0],
					[0,2,2,0]
				]
			]
		}
	}
}

/**
 * 导出模块
 */
export {
	Block1,
	Block2,
	Block3,
	Block4,
	Block5,
	Block6,
	Block7
}
